package com.sk.security.config.security;

import com.alibaba.fastjson.JSONObject;
import com.sk.res.CommonResponseDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * spring security 核心配置类
 *      WebSecurityConfigurerAdapter
 *      管理着Spring Security的整个配置体系，主要包括用户身份认证的管理、全局安全过滤管理和URL访问权限控制的管理。
 * @Author jiaok
 * @Date 2024-03-25 13:47
 */
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@Slf4j
public class SecurityConfiguration  extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    /**
     * 自定义URL访问权限的逻辑
     * 安全过滤器链配置方法
     *      通过重载该方法，可配置如何通过拦截器保护请求。
     *   HttpSecurity 用于构建一个安全过滤器链 SecurityFilterChain .SecurityFilterChain 最终被注入核心过滤器
     * @param http the {@link HttpSecurity} to modify
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/oauth/**","/oauth/token").permitAll()
                .and()
                .formLogin().loginProcessingUrl("/login").successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.getWriter().write(JSONObject.toJSONString(CommonResponseDto.success(authentication.getPrincipal())));
                    }
                }).permitAll()
                    //使用的是jwt，所以并不需要使用csrf
                    .and().csrf().disable();
    }


    /**
     * 配置认证管理器
     * 配置认证管理器 AuthenticationManager
     *  AuthenticationManager的辅助构造方法
     * @param auth the {@link AuthenticationManagerBuilder} to use
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //设置认证的方式-------微信认证，用户名 密码认证
        super.configure(auth);
    }

    /**
     *      身份认证管理器  AuthenticationManager
     *  其是各种类型登录方式、或者Authentication（*AuthenticationToken）辅助认证Provider的管理对象。
     * AuthenticationManager--认证相关的核心接口--同时也是发起认证的出发点，
     *  如果不配置SpringBoot会自动配置一个AuthenticationManager,但由于我们新增了身份认证逻辑，需要需要在此处声明出来，以暴露给oauth2使用
     * @return
     * @throws Exception
     */
    @Override
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }





}
